import subprocess
import time
import pytest
from pathlib import Path
import os

std_outs = []
cmd_history = {}
temp_dir = Path('~/temp/').expanduser()
if not Path(temp_dir).is_dir():
    os.makedirs(temp_dir)
history_max = 50
history_start = 0


def cmd_result_path(std_out, suffix='.std_out'):
    path = temp_dir / str(std_out)
    return path.with_suffix(suffix)


KEY_CMD = 'cmd'
KEY_EXEC_TIME = 'exec_time'
KEY_START_TIME = 'start_time'
KEY_RETURNCODE = 'returncode'
KEY_STD_OUT = 'std_out'


def execute_os_cmd(cmd):
    std_out = outfile(cmd)
    start_time = time.time()
    stdout = open(cmd_result_path(std_out), 'w', encoding = 'utf-8')
    process = subprocess.run(cmd, shell=True, text=True,
                             stderr=subprocess.STDOUT, stdout=stdout)
    exec_time = time.time()-start_time
    cmd_info = {}
    cmd_info[KEY_CMD] = cmd
    cmd_info[KEY_EXEC_TIME] = exec_time
    cmd_info[KEY_START_TIME] = start_time
    cmd_info[KEY_RETURNCODE] = process.returncode
    cmd_info[KEY_STD_OUT] = std_out
    cmd_history[cmd] = cmd_info
    std_outs.append(std_out)
    return cmd_info


def outfile(cmd):
    if cmd in cmd_history:
        return cmd_history[cmd]['std_out']
    else:
        for i in range(history_start, history_start+history_max):
            if i not in std_outs:
                return i
        else:
            older_cmd = sorted(
                cmd_history, key=lambda k: cmd_history[k]['start_time'])[0]
            return cmd_history.pop(older_cmd)['std_out']


@pytest.mark.parametrize('cmd', ['pwd', 'ls', 'cwd'])
def test_execute(cmd):
    cmd_info = execute_os_cmd(cmd)
    print(cmd_info)
    if cmd == 'cwd':
        assert cmd_info['returncode'] != 0
    else:
        assert cmd_info['returncode'] == 0
